<!-- 训练试卷答题页 -->
<template>
  <div class="app-container">
    <!-- 试卷信息 -->
    <div class="paper-header">
      <div class="paper-info">
        <h2>{{ paper.paperName }}</h2>
        <div class="paper-meta">
          <span>总分：{{ paper.totalScore }}分</span>
          <span>题目数：{{ questions.length }}题</span>
          <span>用时：{{ formatDuration }}</span>
        </div>
      </div>
      <div class="paper-actions">
        <el-button type="primary" @click="handleSubmit"> 提交试卷 </el-button>
      </div>
    </div>

    <el-row :gutter="20" class="paper-content">
      <!-- 题目列表 -->
      <el-col :span="18">
        <div
          v-for="(question, index) in questions"
          :key="question.id"
          class="question-item"
          :id="`question-${index + 1}`"
        >
          <div class="question-header">
            <span class="question-index">{{ index + 1 }}.</span>
            <span class="question-type">[单选题]</span>
            <span class="question-score">{{ question.score }}分</span>
          </div>
          <div class="question-content">{{ question.questionText }}</div>
          <div class="question-options">
            <el-radio-group v-model="answers[question.id]">
              <el-radio
                v-for="(option, key) in parseOptions(question.options)"
                :key="key"
                :label="key"
                class="question-option"
              >
                {{ key }}. {{ option }}
              </el-radio>
            </el-radio-group>
          </div>
        </div>
      </el-col>

      <!-- 答题卡 -->
      <el-col :span="6">
        <div class="answer-card">
          <div class="card-header">
            <h3>答题卡</h3>
            <el-tag type="info">
              已答 {{ Object.keys(answers).length }}/{{ questions.length }}
            </el-tag>
          </div>
          <div class="card-content">
            <el-button
              v-for="(_, index) in questions"
              :key="index"
              :type="answers[questions[index].id] ? 'primary' : 'default'"
              size="small"
              class="question-nav-btn"
              @click="scrollToQuestion(index + 1)"
            >
              {{ index + 1 }}
            </el-button>
          </div>
        </div>
      </el-col>
    </el-row>

    <!-- 提交确认对话框 -->
    <el-dialog v-model="submitDialogVisible" title="提交确认" width="400px">
      <div class="submit-confirm">
        <p>是否确认提交试卷？</p>
        <template v-if="hasUnanswered">
          <el-alert type="warning" :closable="false" show-icon>
            还有 {{ questions.length - Object.keys(answers).length }} 题未作答
          </el-alert>
        </template>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="submitDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitPaper">确认提交</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue";
import {
  useRoute,
  useRouter,
  onBeforeRouteLeave as vueRouterBeforeLeave,
} from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  getTrainingPaperDetail,
  getTrainingPaperQuestions,
  submitTrainingPaper,
  saveTrainingAnswers,
  getSavedAnswers,
} from "@/api/training";

const route = useRoute();
const router = useRouter();

// 试卷数据
const paper = ref({});
const questions = ref([]);
const answers = reactive({});

// 对话框控制
const submitDialogVisible = ref(false);

// 计时器
const startTime = ref(Date.now());
const duration = ref(0);
const timer = ref(null);

// 格式化时间
const formatDuration = computed(() => {
  const minutes = Math.floor(duration.value / 60);
  const seconds = duration.value % 60;
  return `${minutes}分${seconds}秒`;
});

// 是否有未答题目
const hasUnanswered = computed(() => {
  return Object.keys(answers).length < questions.value.length;
});

// 添加一个解析选项的方法
const parseOptions = (optionsStr) => {
  try {
    // 将字符串按换行符分割成数组
    const optionArray = optionsStr.split("\n");
    // 创建选项对象
    const optionsObj = {};
    optionArray.forEach((option) => {
      // 分割选项标识和内容 (例如: "A.选项内容" => ["A", "选项内容"])
      const [key, ...content] = option.split(".");
      optionsObj[key] = content.join("."); // 重新组合内容，以防选项内容中包含点号
    });
    return optionsObj;
  } catch (error) {
    console.error("选项解析失败:", error);
    return {}; // 返回空对象作为默认值
  }
};

// 获取试卷信息
const getPaper = async () => {
  try {
    const paperId = route.params.id;
    const [paperData, questionList, savedAnswers] = await Promise.all([
      getTrainingPaperDetail(paperId),
      getTrainingPaperQuestions(paperId),
      getSavedAnswers(paperId),
    ]);

    // 如果试卷已完成，跳转到详情页
    if (paperData.status === 1) {
      ElMessage.warning("该试卷已完成");
      router.replace(`/training/detail/${paperId}`);
      return;
    }

    paper.value = paperData;
    questions.value = questionList;

    // 初始化 answers

    if (savedAnswers) {
      Object.keys(savedAnswers).forEach((key) => {
        answers[key] = savedAnswers[key];
      });
    }
  } catch (error) {
    console.error("获取试卷信息失败：", error);
    ElMessage.error("获取试卷信息失败");
  }
};

// 滚动到指定题目
const scrollToQuestion = (index) => {
  const element = document.getElementById(`question-${index}`);
  if (element) {
    element.scrollIntoView({ behavior: "smooth", block: "start" });
  }
};

// 提交试卷
const handleSubmit = () => {
  submitDialogVisible.value = true;
};

// 确认提交
const submitPaper = async () => {
  try {
    await submitTrainingPaper(paper.value.id, answers);
    ElMessage.success("提交成功");
    // 清空答案
    Object.keys(answers).forEach((key) => {
      delete answers[key];
    });
    // 更新试卷状态
    paper.value.status = 1;
    router.push(`/training/detail/${paper.value.id}`);
  } catch (error) {
    console.error("提交试卷失败：", error);
  }
};

// 自动保存
const autoSave = async () => {
  if (Object.keys(answers).length === 0) return;

  try {
    await saveTrainingAnswers(paper.value.id, answers);
    console.log("自动保存成功");
  } catch (error) {
    console.error("自动保存失败：", error);
  }
};

// 更新时间
const updateDuration = () => {
  duration.value = Math.floor((Date.now() - startTime.value) / 1000);
};

// 页面加载
onMounted(async () => {
  await getPaper();
  // 启动计时器
  timer.value = setInterval(() => {
    updateDuration();
    // 每分钟自动保存一次
    if (duration.value % 60 === 0) {
      autoSave();
    }
  }, 1000);

  // 添加离开提醒
  window.addEventListener("beforeunload", handleBeforeUnload);
});

// 页面卸载
onBeforeUnmount(() => {
  if (timer.value) {
    clearInterval(timer.value);
  }
  window.removeEventListener("beforeunload", handleBeforeUnload);
});

// 离开提醒
const handleBeforeUnload = (e) => {
  if (Object.keys(answers).length > 0 && paper.value.status === 0) {
    e.preventDefault();
    e.returnValue = "";
  }
};

// 路由守卫
const onBeforeRouteLeave = (to, from, next) => {
  if (Object.keys(answers).length > 0 && paper.value.status === 0) {
    ElMessageBox.confirm("您还没有提交试卷，确定要离开吗？", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        // 自动保存一次
        autoSave();
        next();
      })
      .catch(() => {
        next(false);
      });
  } else {
    next();
  }
};

// 注册路由守卫
vueRouterBeforeLeave(onBeforeRouteLeave);
</script>

<style scoped>
.paper-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.paper-info h2 {
  margin: 0 0 10px 0;
  font-size: 20px;
}

.paper-meta {
  color: #666;
  font-size: 14px;
}

.paper-meta span {
  margin-right: 20px;
}

.paper-content {
  margin-top: 20px;
}

.question-item {
  margin-bottom: 30px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.question-header {
  margin-bottom: 15px;
}

.question-index {
  font-weight: bold;
  margin-right: 10px;
}

.question-type {
  color: #666;
  margin-right: 10px;
}

.question-score {
  color: #f56c6c;
}

.question-content {
  margin-bottom: 15px;
  line-height: 1.6;
}

.question-options {
  padding-left: 20px;
}

.question-option {
  display: block;
  margin-bottom: 10px;
}

.answer-card {
  position: sticky;
  top: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.card-header h3 {
  margin: 0;
  font-size: 16px;
}

.card-content {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}

.question-nav-btn {
  width: 100%;
}

.submit-confirm {
  text-align: center;
}

.submit-confirm p {
  margin-bottom: 20px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
